package cn.pugle.base.reflect;

import org.apache.commons.lang3.StringUtils;
import org.objenesis.ObjenesisStd;

import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 测试Class类的一些反射相关方法
 */
@SuppressWarnings("all")
public class Parent implements Comparable {
    static String staticVar = "parent's staticVar";
    String var = "parent's var";

    public Parent() {
        System.out.println("parent constructor");
    }

    public String get() {
        return var;
    }

    public String staticGet() {
        return staticVar;
    }

    public static String aStaticMethod() {
        return "xxx2";
    }


    public static void main(String[] args) throws Exception {
        invokeMethod();
    }

    public static void handleMethod() throws Exception {
        MethodHandles.lookup();
//        LambdaMetafactory.metafactory();
    }

    public static void invokeMethod() throws Exception {
        Class<?> aClass = Class.forName("cn.pugle.base.reflect.Parent");
        Method getMethod = aClass.getDeclaredMethod("aStaticMethod");
        Object result = getMethod.invoke(null);
        System.out.println(result);
    }

    @Override
    public int compareTo(Object o) {
        return 0;
    }

    public static class InnerSCls {
    }

    public class InnerCls {
    }
}

@SuppressWarnings("all")
class Son extends Parent {
    static String staticVar = "son's staticVar";
    String var = "son's var";

    public Son(String haha) {
        System.out.println("son constructor");
    }

    public static void classInfos() {
        Parent parent = new Parent();
        Son son = new Son("haha");

        System.out.println("Son getInterfaces: " + StringUtils.join(Son.class.getInterfaces()));
        System.out.println("Parent getInterfaces: " + StringUtils.join(Parent.class.getInterfaces()));

        System.out.println("Son getGenericInterfaces: " + StringUtils.join(Son.class.getGenericInterfaces()));
        System.out.println("Parent getGenericInterfaces: " + StringUtils.join(Parent.class.getGenericInterfaces()));

        System.out.println("Son getClasses: " + StringUtils.join(Son.class.getClasses()));
        System.out.println("Parent getClasses: " + StringUtils.join(Parent.class.getClasses()));

        System.out.println("Son getDeclaredClasses: " + StringUtils.join(Son.class.getDeclaredClasses()));
        System.out.println("Parent getDeclaredClasses: " + StringUtils.join(Parent.class.getDeclaredClasses()));

        System.out.println("Son getSuperclass: " + StringUtils.join(Son.class.getSuperclass()));
        System.out.println("Parent getSuperclass: " + StringUtils.join(Parent.class.getSuperclass()));

        System.out.println("Son getGenericSuperclass: " + StringUtils.join(Son.class.getGenericSuperclass()));
        System.out.println("Parent getGenericSuperclass: " + StringUtils.join(Parent.class.getGenericSuperclass()));
    }

    public static void newInstance() throws IllegalAccessException, InstantiationException {
        Parent parent = Parent.class.newInstance();
//        Son son = Son.class.newInstance();//NoSuchMethodException
        ObjenesisStd objenesisStd = new ObjenesisStd();//屌炸的绕过语言限制, 使用反射/sun.reflect进行newInstance
        Son son = objenesisStd.newInstance(Son.class);


        List list = objenesisStd.newInstance(List.class);
    }
    public static void main(String[] args) throws Exception {
        newInstance();
    }

    public String get() {
        return var;
    }

    public String staticGet() {
        return staticVar;
    }
}
